﻿using System;
using System.Collections.Concurrent;
using System.Collections.Generic;
using System.Linq;
using System.Reflection;
using Sharp.Infrastructure;
using Sharp.Portal.Other;
using Sharp.Infrastructure.IoC;
using Sharp.Portal.Owin;

namespace Sharp.Portal.Mvc.List
{
    public partial class SharpList
    {
        //用来缓存模型定义
        private static readonly ConcurrentDictionary<Type, Dictionary<PropertyInfo, ListModelInfo>> ColumnInfos =
            new ConcurrentDictionary<Type, Dictionary<PropertyInfo, ListModelInfo>>();

        #region 获取模型的列定义

        /// <summary>
        /// 获取模型的列定义
        /// </summary>
        /// <returns></returns>
        protected Dictionary<PropertyInfo, ListModelInfo> GetColumnInfos()
        {
            if (ServiceLocator.Instance.IsRegistered<ISharpColumn>())
            {
                return ColumnInfos.GetOrAdd(this.GetType(), ServiceLocator.Instance.GetService<ISharpColumn>().GetColumnInfos);
            }

            return ColumnInfos.GetOrAdd(this.GetType(), (dic) =>
            {
                var outPut = new Dictionary<PropertyInfo, ListModelInfo>();
                foreach (var property in dic.GetProperties())
                {
                    var column =
                        property.GetCustomAttributes(typeof(ColumnAttribute), false).FirstOrDefault() as ColumnAttribute;
                    if (column == null) continue;

                    var queryOption = property.GetCustomAttributes(typeof(QueryOptionAttribute), false).FirstOrDefault() as QueryOptionAttribute ?? new QueryOptionAttribute();

                    outPut.Add(property, new ListModelInfo()
                    {
                        Attribute = column,
                        Order = column.Order,
                        Property = property,
                        QueryOption = queryOption.Option
                    });
                }

                outPut = outPut.OrderBy(x => x.Value.Order)//.ThenByDescending(x => x.Key)
                    .ToDictionary(k => k.Key, v => v.Value);

                return outPut;
            });
        }
        #endregion


        #region 是否含有有效锁定列
        /// <summary>
        /// 是否含有有效锁定列
        /// </summary>
        /// <returns></returns>
        public bool HasLockColumn()
        {
            foreach (var item in this.ColumnItems)
            {
                if (item.Hidden) continue;
                return item.Locked;
            }
            return false;
        }
        #endregion

        #region 从左边锁多少列
        /// <summary>
        /// 从左边锁多少列
        /// </summary>
        /// <returns></returns>
        public int LockLeftColumns()
        {
            var index = 0;
            if (Feature.HasFlag(ListFeature.MultiSelect))
            {
                index++;
            }
            if (Feature.HasFlag(ListFeature.RowNumber))
            {
                index++;
            }

            foreach (var item in this.ColumnItems)
            {
                if (item.Hidden) continue;
                if (!item.Locked)
                {
                    return index;
                }
                else
                {
                    index++;
                }
            }
            return index;
        }
        #endregion

        #region 初始化数据列表
        /// <summary>
        /// 初始化数据列表
        /// </summary>
        protected virtual void InitDataList()
        {
            foreach (var columnItem in GetColumnInfos())
            {
                ColumnAttribute column = columnItem.Value.Attribute;
                PropertyInfo property = columnItem.Key;

                var item = new ColumnItem();
                item.Text = column.Text;
                item.Name = property.Name;
                item.Align = column.Align;
                item.QueryFeatureOption = columnItem.Value.QueryOption;

                if (column.DataIndex.IsNullOrEmpty())
                {
                    item.DataIndex = item.Name;
                }
                else
                {
                    item.DataIndex = column.DataIndex;
                }

                if (column.Locked)
                {
                    item.Feature |= ColumnFeature.Locked;
                }
                if (column is NumberColumnAttribute)
                {
                    item.Feature |= ColumnFeature.NumberColumn;
                    item.Format = (column as NumberColumnAttribute).Format;
                    item.QueryFeature(QueryFeature.FromToQuery);
                }
                if (column is TemplateColumnAttribute)
                {
                    item.Feature |= ColumnFeature.TemplateColumn;
                    item.Template = (column as TemplateColumnAttribute).TemplateString;
                }
                if (column is DateColumnAttribute)
                {
                    item.Feature |= ColumnFeature.DateColumn;
                    item.Format = (column as DateColumnAttribute).Format;
                    item.QueryFeature(QueryFeature.FromToQuery);
                }
                if (column is BooleanColumnAttribute)
                {
                    item.Feature |= ColumnFeature.BooleanColumn;
                    item.FalseText = (column as BooleanColumnAttribute).FalseText;
                    item.TrueText = (column as BooleanColumnAttribute).TrueText;

                    if (item.FalseText.IsNullOrEmpty()) item.FalseText = "否";
                    if (item.TrueText.IsNullOrEmpty()) item.TrueText = "是";


                    item.QueryFeature(QueryFeature.CheckBoxGroupQuery);
                }
                if (column is TreeColumnAttribute)
                {
                    item.Feature |= ColumnFeature.TreeColumn;
                    item.Template = (column as TemplateColumnAttribute).TemplateString;
                }
                item.Width = column.Width;
                item.Hidden = column.Hidden;
                item.Order = column.Order;
                item.Locked = column.Locked;
                item.Sortable = column.Sortable;
                if (item.QueryFeatureOption.HasFlag(QueryFeature.DefualtQuery))
                {
                    item.QueryFeature(QueryFeature.DefualtQuery | QueryFeature.Queryable);
                }

                if (property.GetCustomAttributes(typeof(MasterDataAttribute), true).FirstOrDefault() is MasterDataAttribute md)
                {
                    item.MasterDataCategory = md.Category;
                    item.IsTree = md.IsTree;
                    item.QueryFeature(QueryFeature.EqualMatchString);
                }

                foreach (ClientDrawRowAttribute cdr in property.GetCustomAttributes(typeof(ClientDrawRowAttribute), true))
                {
                    item.AppendClientDrawRow(cdr.Condition, cdr.Color);
                }

                ColumnItems.Add(item);
            }

            ColumnItems = ColumnItems.OrderBy(x => x.Order).ToList();
        }
        #endregion

        /// <summary>
        /// 导入javascript
        /// </summary>
        public string ImportJavascript { get; set; }
        /// <summary>
        /// 导入css
        /// </summary>
        public string ImportCss { get; set; }

        /// <summary>
        /// 通过配置文件修改列属性
        /// </summary>
        /// <param name="moduleId"></param>
        /// <returns></returns>
        public CustomColumns GetCustomColumns(string moduleId = "")
        {
            //if (moduleId.Length == 0)
            //{
            //    moduleId = this.ModuleId;
            //    if (this.RootModule.Length > 0)
            //        moduleId = this.RootModule + "_" + moduleId;
            //}

            if (moduleId.IsNullOrEmpty())
            {
                moduleId = this.ModuleId;
            }
            CustomColumns result;
            string key = string.Format("CustomColumns_{0}_{1}", moduleId, SharpUserManager.Current.Id);

            if (!CustomColumns.DicCustomColumns.TryGetValue(key, out result))
            {
                result = new CustomColumns();
                if (result.LoadFromFile(SharpUserManager.Current.Id, moduleId))
                {
                    //return result;
                }
            }
            if (result.Columns.Count == 0)
            {
                foreach (var c in this.ColumnItems)
                {
                    result.Columns.Add(new CustomColumnItem(c.DataIndex)
                    {
                        Hidden = c.Hidden
                    });
                }
            }
            else
            {
                foreach (var c in this.ColumnItems)
                {
                    var cc = result.Columns.FirstOrDefault(x => x.Name == c.DataIndex);
                    if (cc == null) continue;
                    if (cc.Width > 0)
                        c.Width = cc.Width;
                    c.Hidden = cc.Hidden;
                    c.Order = result.IndexOf(c.Name);
                }
            }

            if (result.Columns.Any())
            {
                CustomColumns.DicCustomColumns.AddOrUpdate(key, result, (x, y) => result);
            }

            return result;
        }
        /// <summary>
        /// 获取列的字段信息
        /// </summary>
        /// <returns></returns>
        public object GetColumnFields()
        {
            InitDataList();
            List<ColumnItem> list = new List<ColumnItem>();
            foreach (var columnItem in GetColumnInfos().Where(x => !x.Value.Attribute.Hidden))
            {
                ColumnAttribute column = columnItem.Value.Attribute;
                PropertyInfo property = columnItem.Key;

                var item = new ColumnItem();
                item.Text = column.Text;
                item.Name = property.Name;
                if (column.DataIndex.IsNullOrEmpty())
                {
                    item.DataIndex = item.Name;
                }
                else
                {
                    item.DataIndex = column.DataIndex;
                }
                list.Add(item);
            }

            return list;
        }
    }
}
